import { lazyReportCache } from '../utils/report.js'
import {onCachePageshow, getSelector, getPagePath} from '../utils/common.js'
import { config } from '../config.js'

export default function error() {
    /**
     * 监听控制台错误
     * */
    const consoleError = window.console.error // 保存原始方法
    window.console.error = (...args) => {
        consoleError.apply(this, args) // 输出原始错误信息
        const data = {
            type: 'error',
            subType: 'console-error',
            pagePath: getPagePath(),
            startTime: performance.now(),
            errData: args,
        }
        lazyReportCache(data)
    }

    // 捕获资源加载失败错误 js css img...
    window.addEventListener('error', event => {
        const target = event.target
        if (!target) return
        if (target.src || target.href) {
            const url = target.src || target.href
            const data = {
                type: 'error',
                subType: 'resource',
                pagePath: getPagePath(),
                startTime: event.timeStamp, // 从页面加载开始计时
                url,
                html: target.outerHTML,
                resourceType: target.tagName.toLowerCase(), // img script link 等资源类型
                selector: getSelector(target), // 最后一个操作的元素
            }
            lazyReportCache(data)
        }
    }, true)

    // 监听 js 错误
    window.onerror = (msg, url, line, column, error) => {
        const data = {
            type: 'error',
            subType: 'js',
            pagePath: url,
            startTime: performance.now(),
            msg,
            line,
            column,
            error: error.stack,
        }
        lazyReportCache(data)
    }

    // 监听 promise 错误 缺点是获取不到列数据
    window.addEventListener('unhandledrejection', event => {
        const data = {
            type: 'error',
            subType: 'promise',
            pagePath: getPagePath(),
            startTime: event.timeStamp,
            reason: event.reason?.stack ? event.reason?.stack : event.reason,
        }
        lazyReportCache(data)
    })

    if (config.vue?.instance) {
        config.vue.instance.config.errorHandler = (err, vm, info) => {
            const data = {
                type: 'error',
                subType: 'vue',
                pagePath: getPagePath(),
                startTime: performance.now(),
                info,
                error: err.stack,
            }
            lazyReportCache(data)
        }
    }

    onCachePageshow(() => {
        error()
    })
}
